package cn.cnf.service.impl;

import cn.cnf.common.Result;
import cn.cnf.common.StringPool;
import cn.cnf.common.enums.StatusCode;
import cn.cnf.common.exception.CustomException;
import cn.cnf.common.utils.JwtTokenUtil;
import cn.cnf.entity.Role;
import cn.cnf.entity.User;
import cn.cnf.mapper.UserMapper;
import cn.cnf.service.IMailService;
import cn.cnf.service.RoleService;
import cn.cnf.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

/**
 * 服务接口实现
 *
 * @author ZhuMeiYi
 * @description
 * @since 2020-12-03 12:47:52
 */
@Slf4j
@RequiredArgsConstructor(onConstructor = @_(@Autowired))
@Service
@Transactional(rollbackFor = {RuntimeException.class, Error.class})
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;

    @Autowired
    private RoleService roleService;
    @Autowired
    private IMailService iMailService;

    @Override
    public User findUserByUsername(String username) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (user == null) {
            throw new CustomException("没有找到用户");
        }
        return user;
    }

    @Override
    public Role[] findRoleByUsername(String username) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (user == null) {
            throw new CustomException("没有找到用户");
        }
        List<Role> roles = roleService.list(new LambdaQueryWrapper<Role>().in(Role::getRoleId, Arrays.asList(user.getRoleId().split(","))));

        return roles.toArray(new Role[0]);

    }

    @Override
    public String register(User user) {
        user.setId(null);
        user.setRoleId("2");
        if (usernameExist(user.getUsername())) {
            throw new CustomException("用户名已存在");
        }
        save(user);
        return user.getId();
    }

    /**
     * 判断用户名是否存在 存在返回是 不存在返回否
     *
     * @param username
     * @return
     */
    @Override
    public boolean usernameExist(String username) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().select(User::getId).eq(User::getUsername, username));
        return user != null;
    }

    @Override
    public String updateByUsername(User user) {
        // 设置不可变内容
        user.setId(null);
        user.setRoleId(null);
        user.setCreateTime(null);
        user.setMoney(null);
        // 更新
        boolean result = update(user, new LambdaUpdateWrapper<User>().eq(User::getUsername, user.getUsername()));
        if (result) {
            return user.getUsername();
        } else {
            throw new CustomException("用户信息更新失败");
        }
    }

    @Override
    public void sendPasswordEmail(String username) {
        User user = findUserByUsername(username);
        if (user==null){
            throw new CustomException("找不到此用户");
        }
        if (StringUtils.isBlank(user.getEmail())){
            throw new CustomException("该用户没有填入邮箱地址");
        }
        String token = JwtTokenUtil.createToken(username, StringPool.PASSWORD_RESET_MARK);
        iMailService.sendHtmlMail(user.getEmail(),"CNFun账号密码重置","点击<a href=\"http://localhost:8080/password/newPassword?token="+token+"\">这里</a>以重置"+username+"的密码。如非本人操作，请无视本邮件。");
    }

    @Override
    public String resetPasswordByToken(String token,String password) {
        if (StringUtils.isBlank(token)){
            throw new CustomException("未输入token");
        }
        if (!StringPool.PASSWORD_RESET_MARK.equals(JwtTokenUtil.getUserRole(token))){
            throw new CustomException("不合理的token");
        }
        String username = JwtTokenUtil.getUsername(token);
        User user = findUserByUsername(username);
        if (user==null){
            throw new CustomException("未找到用户");
        }
        user.setPassword(password);
        return user.getId();

    }

    @Override
    public Object checkPwd(String pwd, String id) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                                        .eq(User::getId,id));
        if(pwd.equals(user.getPassword())){
            return true;
        }else{
            throw new CustomException("输入密码与原密码不符");
        }
    }

    @Override
    public Object changePwd(User user) {
        //老密码跟数据库密码校验
        LambdaUpdateWrapper<User> wrapper1 = Wrappers.lambdaUpdate();
        wrapper1.eq(User::getId,user.getId());
        userMapper.update(user,wrapper1);
        return true;
    }

    @Override
    public IPage getAllUser(String name, Integer current, Integer pageSize, Page<User> iPage) {
        iPage.setCurrent (current);
        iPage.setSize (pageSize);
        IPage<User> page = new Page<> ();
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.like(name!=null,User::getUsername,name);
        page = userMapper.selectPage (iPage,wrapper);
        return page;
    }

    private User getMaster() {
        return userMapper.selectOne(new LambdaQueryWrapper<User>().like(User::getId, 0));
    }
}